﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Reflection;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.Diagnostics;

namespace Elentok.Common.Wpf.ViewModels.Dialogs
{
  /// <summary>
  /// Defines the view model of the about dialog
  /// </summary>
  public interface IAboutDialogViewModel
  {
    /// <summary>
    /// Gets the image.
    /// </summary>
    /// <value>The image.</value>
    ImageSource Image { get; }

    /// <summary>
    /// Gets the title.
    /// </summary>
    /// <value>The title.</value>
    string Title { get; }

    /// <summary>
    /// Gets the description.
    /// </summary>
    /// <value>The description.</value>
    string Description { get; }

    /// <summary>
    /// Gets the copyrights.
    /// </summary>
    /// <value>The copyrights.</value>
    string Copyrights { get; }

    /// <summary>
    /// Gets the home page URL.
    /// </summary>
    /// <value>The home page URL.</value>
    string HomePageUrl { get; }

    /// <summary>
    /// Gets the email.
    /// </summary>
    /// <value>The email.</value>
    string Email { get; }

    /// <summary>
    /// Gets the license.
    /// </summary>
    /// <value>The license.</value>
    string License { get; }

    /// <summary>
    /// Gets the credits.
    /// </summary>
    /// <value>The credits.</value>
    ObservableCollection<IAboutDialogCredit> Credits { get; }

    /// <summary>
    /// Gets a value indicating whether this instance has credits.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if this instance has credits; otherwise, <c>false</c>.
    /// </value>
    bool HasCredits { get; }
  }

  /// <summary>
  /// The view model of the about dialog
  /// </summary>
  public class AboutDialogViewModel : ViewModelBase, IAboutDialogViewModel
  {
    #region Fields

    private ImageSource image;
    private string homePageUrl;
    private string email;
    private string license;

    #endregion

    #region Ctor

    /// <summary>
    /// Initializes a new instance of the <see cref="AboutDialogViewModel"/> class.
    /// </summary>
    public AboutDialogViewModel()
    {
      var info = new AssemblyExtendedInfo(Assembly.GetEntryAssembly());
      this.Title = string.Format("About {0} {1}", info.Title, info.ProductVersion);
      this.Description = info.Description;
      this.Copyrights = info.Copyrights;
      this.Credits = new ObservableCollection<IAboutDialogCredit>();
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets or sets the image
    /// </summary>
    public ImageSource Image
    {
      get
      {
        return this.image;
      }
      set
      {
        if (this.image == value)
          return;

        OnPropertyChanging("Image");
        this.image = value;
        OnPropertyChanged("Image");
      }
    }

    /// <summary>
    /// Gets the copyrights.
    /// </summary>
    /// <value>The copyrights.</value>
    public string Copyrights { get; private set; }

    /// <summary>
    /// Gets the description.
    /// </summary>
    /// <value>The description.</value>
    public string Description { get; private set; }

    /// <summary>
    /// Gets the title.
    /// </summary>
    /// <value>The title.</value>
    public string Title { get; private set; }

    /// <summary>
    /// Gets the home page URL.
    /// </summary>
    /// <value>The home page URL.</value>
    public string HomePageUrl
    {
      get
      {
        return this.homePageUrl;
      }
      set
      {
        if (this.homePageUrl == value)
          return;

        OnPropertyChanging("HomePageUrl");
        this.homePageUrl = value;
        OnPropertyChanged("HomePageUrl");
      }
    }

    /// <summary>
    /// Gets the email.
    /// </summary>
    /// <value>The email.</value>
    public string Email
    {
      get
      {
        return this.email;
      }
      set
      {
        if (this.email == value)
          return;

        OnPropertyChanging("Email");
        this.email = value;
        OnPropertyChanged("Email");
      }
    }

    /// <summary>
    /// Gets the credits.
    /// </summary>
    /// <value>The credits.</value>
    public ObservableCollection<IAboutDialogCredit> Credits { get; private set; }

    /// <summary>
    /// Gets a value indicating whether this instance has credits.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if this instance has credits; otherwise, <c>false</c>.
    /// </value>
    public bool HasCredits
    {
      get { return Credits.Count > 0; }
    }

    /// <summary>
    /// Gets or sets the license.
    /// </summary>
    /// <value>The license.</value>
    public string License
    {
      get
      {
        return this.license;
      }
      set
      {
        if (this.license == value)
          return;

        OnPropertyChanging("License");
        this.license = value;
        OnPropertyChanged("License");
      }
    }

    #endregion
  }

  #region Credit

  /// <summary>
  /// Credit information (about libraries used in this app and people that helped)
  /// </summary>
  public interface IAboutDialogCredit
  {
    /// <summary>
    /// Gets the header.
    /// </summary>
    /// <value>The header.</value>
    string Header { get; }

    /// <summary>
    /// Gets the URL.
    /// </summary>
    /// <value>The URL.</value>
    string Url { get; }

    /// <summary>
    /// Gets the description.
    /// </summary>
    /// <value>The description.</value>
    string Description { get; }

    /// <summary>
    /// Gets the open URL command.
    /// </summary>
    /// <value>The open URL command.</value>
    ICommand OpenUrlCommand { get; }
  }

  /// <summary>
  /// Credit information (about libraries used in this app and people that helped)
  /// </summary>
  public class AboutDialogCredit : IAboutDialogCredit
  {
    /// <summary>
    /// Initializes a new instance of the <see cref="AboutDialogCredit"/> class.
    /// </summary>
    public AboutDialogCredit()
    {
      this.OpenUrlCommand = new DelegateCommand<object>(
        delegate
        {
          Process.Start(this.Url);
        });

    }

    /// <summary>
    /// Gets or sets the header.
    /// </summary>
    /// <value>The header.</value>
    public string Header { get; set; }

    /// <summary>
    /// Gets the URL.
    /// </summary>
    /// <value>The URL.</value>
    public string Url { get; set; }

    /// <summary>
    /// Gets the description.
    /// </summary>
    /// <value>The description.</value>
    public string Description { get; set; }

    /// <summary>
    /// Gets the open URL command.
    /// </summary>
    /// <value>The open URL command.</value>
    public ICommand OpenUrlCommand { get; set; }
  }

  #endregion
}
